import 'dart:convert';

import 'package:flutter/material.dart';

import 'alignment.dart';
import 'option_bean.dart';
import 'rendertype.dart';

class OrdinaryDropdownBox<T> extends StatefulWidget {
  // @required 下拉框宽度、下拉面板的宽度
  final double width;

  // @required 下拉列表的数据
  List<T> items;

  // @required 被选中的内容
  T value;

  // @required 配置项
  OptionBean reference;

  // 选中的数据
  Function onChange;

  // 占位符
  final String placeholder;

  // 右侧操作icon
  double operIconSize;

  // -- 样式类
  // 组件高度
  double height;

  // 回显的字号
  double fontSize;

  // 组件样式
  Decoration decoration;

  // 下拉列表的字号
  double dropDownFontSize;

  // 下拉列表中选中数据的字体颜色
  Color selectedFontColor;

  // 占位符，回显文字的对齐方式
  ALIGNMENT alignments;

  // 自定义组件样式
  static const _decoration = BoxDecoration(color: Colors.white);

  /// 下拉选择框
  /// * [width] double|组件宽度|必填
  /// * [items] List<T>|下拉列表的数据|必填
  /// * [value] T|选中的数据|必填
  /// * [reference] OptionBean|配置项|必填|需要渲染的字段及比对的字段
  /// * [onChange] Function|内容改变的回调|选填
  /// * [placeholder] String|占位符|选填
  /// * [operIconSize] double|右侧icon图标尺寸|选填
  /// * [height] double|组件的高度|选填
  /// * [fontSize] double|回显的字号|选填
  /// * [decoration] Decoration|组件的样式|选填
  /// * [dropDownFontSize] double|下拉列表字号|选填
  /// * [selectedFontColor] Color|下拉列表中选中文字的样式|选填
  /// * [alignments] ALIGNMENT|文字对齐方式|选填
  OrdinaryDropdownBox({
    Key key,
    @required this.width,
    @required this.items,
    @required this.value,
    @required this.reference,
    this.onChange,
    this.placeholder = "请选择...",
    this.operIconSize = 30,
    this.height = 40,
    this.fontSize = 15.0,
    this.decoration = _decoration,
    this.dropDownFontSize = 15.0,
    this.selectedFontColor,
    this.alignments = ALIGNMENT.LEFT,
  }) : super(key: key);

  @override
  OrdinaryDropdownBoxState createState() => new OrdinaryDropdownBoxState();
}

class OrdinaryDropdownBoxState<T> extends State<OrdinaryDropdownBox> {
  // 左侧内边距（内容与左侧边的距离）
  double leftPadding = 10.0;

  // 深度备份
  List<T> backupList;

  @override
  Widget build(BuildContext context) {
    // 将list进行备份
    backupList = List.from(widget.items);

    return Container(
      width: widget.width,
      height: widget.height ?? 40,
      decoration: widget.decoration,
      child: Row(
        children: [
          Container(
            padding: EdgeInsets.only(left: leftPadding),
            width: widget.width - widget.operIconSize,
            child: DropdownButton(
              underline: SizedBox.shrink(),
              icon: SizedBox.shrink(),
              hint: Container(
                width: widget.width - (widget.operIconSize + leftPadding),
                alignment:
                    _rAlignmentGeometry(widget.alignments ?? ALIGNMENT.LEFT),
                child: Text(
                  "${widget.placeholder}",
                  textAlign: _rTextAlign(widget.alignments ?? ALIGNMENT.LEFT),
                  overflow: TextOverflow.ellipsis,
                  maxLines: 1,
                  style: TextStyle(
                    fontSize: widget.fontSize,
                    color: Colors.black38,
                  ),
                ),
              ),
              selectedItemBuilder: (BuildContext ct) => _createSelectItem(),
              items: _createListItem(),
              value: widget.value,
              onChanged: (val) {
                setState(() {
                  widget.value = val;
                });

                // 执行回调函数
                if (widget.onChange != null && widget.onChange is Function)
                  widget.onChange(val);
              },
            ),
          ),

          // -
          InkWell(
            onTap: () {
              if (widget.value != null) {
                setState(() {
                  widget.value = null;
                });
                // 执行清空回调
                // if (widget.onEmpty != null) widget.onEmpty();
                if (widget.onChange != null && widget.onChange is Function)
                  widget.onChange(null);
              }
            },
            child: Container(
              width: widget.operIconSize,
              height: widget.operIconSize,
              child: widget.value != null
                  ? Icon(
                      Icons.cancel,
                      size: widget.operIconSize - leftPadding,
                      color: Colors.black12,
                    )
                  : Icon(
                      Icons.chevron_right,
                      size: widget.operIconSize - leftPadding,
                      color: Colors.black12,
                    ),
            ),
          ),
        ],
      ),
    );
  }

  /// 创建下拉列表（用于展示下拉数据）
  List<DropdownMenuItem> _createListItem() {
    List<DropdownMenuItem> _lw = [];

    // 检查数据长度
    if (widget.items.length > 0) {
      _lw = _createDropdownMenuItem<List<DropdownMenuItem>>(
        _lw,
        widget.items,
        RENDERTYPE.LISTECHO,
      );
    } else
      print("没有可渲染的下拉框数据");

    return _lw;
  }

  /// 创建选中后数据样式
  List<Widget> _createSelectItem() {
    List<Widget> _lw = [];
    if (widget.items.length > 0)
      _lw = _createDropdownMenuItem<List<Widget>>(
        _lw,
        widget.items,
        RENDERTYPE.SELECTEDECHO,
      );

    return _lw;
  }

  /// 创建DropdownMenuItem列表
  /// * [vessel] -
  /// * [list] list|基础数据|必填
  /// * [type] _RENDERTYPE|渲染的类型|必填
  S _createDropdownMenuItem<S>(S vessel, List list, RENDERTYPE type) {
    Map _m;
    List _vessel = vessel as List;

    for (int i = 0, len = list.length; i < len; i++) {
      // 将list<T>中的每一项数据转化为Map
      _m = json.decode(json.encode(list[i]));

      // 创建下拉数据列表
      _vessel.add(
        DropdownMenuItem<T>(
          child: Container(
            width: widget.width - (widget.operIconSize + leftPadding),
            child: Text(
              _m[widget.reference.showContent],
              textAlign: type == RENDERTYPE.SELECTEDECHO
                  ? _rTextAlign(widget.alignments ?? ALIGNMENT.LEFT)
                  : null,
              overflow: type == RENDERTYPE.SELECTEDECHO
                  ? TextOverflow.ellipsis
                  : null,
              maxLines: type == RENDERTYPE.SELECTEDECHO ? 1 : null,
              style: type == RENDERTYPE.SELECTEDECHO
                  ? TextStyle(fontSize: widget.fontSize ?? 15)
                  : _createSelectedStyle(
                      widget.value,
                      _m[widget.reference.contrast],
                    ),
            ),
          ),
          value: backupList[i],
        ),
      );
    }

    return vessel;
  }

  /// 创建选中数据的样式
  /// * [reference] dynamic|参考值|必填
  /// * [result] String|对比值|必填
  TextStyle _createSelectedStyle(dynamic reference, String result) {
    TextStyle style;
    if (reference == null) {
      style = TextStyle(
          color: Colors.black87, fontSize: widget.dropDownFontSize ?? 15);
    } else {
      style = TextStyle(
        color: reference.id == result
            ? widget.selectedFontColor ?? Theme.of(context).primaryColor
            : Colors.black87,
        fontSize: widget.dropDownFontSize ?? 15,
      );
    }
    return style;
  }

  /// 占位符文字对齐方式
  /// * [alig] ALIGNMENT|必填
  AlignmentGeometry _rAlignmentGeometry(ALIGNMENT alig) {
    switch (alig) {
      case ALIGNMENT.LEFT:
        return Alignment.centerLeft;
      case ALIGNMENT.RIGHT:
        return Alignment.centerRight;
      case ALIGNMENT.CENTER:
        return Alignment.center;
      default:
        return Alignment.centerLeft;
    }
  }

  /// 文字对齐方式
  /// * [alig] ALIGNMENT|必填
  TextAlign _rTextAlign(ALIGNMENT alig) {
    switch (alig) {
      case ALIGNMENT.LEFT:
        return TextAlign.left;
      case ALIGNMENT.RIGHT:
        return TextAlign.right;
      case ALIGNMENT.CENTER:
        return TextAlign.center;
      default:
        return TextAlign.left;
    }
  }
}
